home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
program
/
vol16n13.zip
/
OPENTR.ZIP
/
OT_SRC.ZIP
/
OTDOC.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1997-05-26
|
13KB
|
437 lines
// OTDoc.cpp : implementation of the COpenTrapDoc class
//
// OpenTrap Version 1.00 by Gregory A. Wolking
// Copyright ⌐ 1997 Ziff-Davis Publishing
// First published in PC Magazine, US Edition, July 1997.
#include "stdafx.h"
#include "OpenTrap.h"
#include "OTDoc.h"
#include "OTView.h"
#include "OTextern.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// COpenTrapDoc
IMPLEMENT_DYNCREATE(COpenTrapDoc, CDocument)
BEGIN_MESSAGE_MAP(COpenTrapDoc, CDocument)
//{{AFX_MSG_MAP(COpenTrapDoc)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// COpenTrapDoc construction/destruction
COpenTrapDoc::COpenTrapDoc()
{
// Allocate record buffer.
if (g_pBufferStart == NULL)
g_pBufferStart = new char[g_intLogSizeK * 1024];
m_bIsExporting = FALSE;
SetFilterFlag();
}
COpenTrapDoc::~COpenTrapDoc()
{
// Delete record buffer.
if (g_pBufferStart)
{
delete [] g_pBufferStart;
g_pBufferStart = NULL;
}
}
BOOL COpenTrapDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
if (g_pBufferStart == NULL) // Make sure buffer exists.
{
MessageBox(NULL, "Could not allocate memory", "OpenTrap", MB_ICONINFORMATION);
return FALSE;
}
g_pNextRec = g_pBufferStart; // Reset pointers and flags to indicate buffer is empty.
g_intRecCount = 0;
g_bLogFull = FALSE;
g_pLastRecord = NULL;
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// COpenTrapDoc serialization
void COpenTrapDoc::Serialize(CArchive& ar)
{
CDocument::Serialize(ar);
if (ar.IsStoring())
{
// Write signature
ar.Write("otlog", 6);
// Write record count
ar.Write(&g_intRecCount, sizeof(g_intRecCount));
// followed by raw data.
ar.Write(g_pBufferStart, g_pNextRec - g_pBufferStart);
}
else
{
// Get pointer to file object.
CFile * cf = ar.GetFile();
// Get file size.
DWORD len = cf->GetLength();
// Default result is bad format.
UINT result = IDP_BAD_FILE_FORMAT;
DWORD count = 0, data_size;
UINT bytes_read;
char signature[6];
// File must be at least large enough to
// hold 6 byte signature, DWORD for the record count,
// and one record (empty logs cannot be saved).
if (len > (6 + sizeof(DWORD) + sizeof(struct packed_record) + 1))
{
// Verify that file signature (first six bytes) is "otlog" in ASCIIZ format.
if (ar.Read(signature, 6) == 6)
{
if (lstrcmp(signature, "otlog") == 0)
{
// Retrieve record count.
if (ar.Read(&count, sizeof(count)) == sizeof(count))
{
// See how much data there is to load.
data_size = len - 6 - sizeof(count);
// Make sure buffer is large enough.
if (Check_Buffer_Size(data_size))
{
// Read data into buffer
bytes_read = ar.Read(g_pBufferStart, data_size);
// If successful,
if (bytes_read == data_size)
{
// Clear error status
result = 0;
// and set new record count.
g_intRecCount = count;
}
}
else
result = IDP_BUFFER_ALLOC_FAIL;
}
}
}
}
// If result code is non-zero,
if (result)
// Display corresponding error message.
AfxMessageBox(result, 0);
else
// Otherwise, update record pointers.
Fix_Pointers(count);
}
}
/////////////////////////////////////////////////////////////////////////////
// COpenTrapDoc diagnostics
#ifdef _DEBUG
void COpenTrapDoc::AssertValid() const
{
CDocument::AssertValid();
}
void COpenTrapDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// COpenTrapDoc commands
BOOL COpenTrapDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
if (!CDocument::OnOpenDocument(lpszPathName))
return FALSE;
UpdateAllViews(NULL, 0, 0);
return TRUE;
}
BOOL COpenTrapDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
return CDocument::OnSaveDocument(lpszPathName);
}
// Makes sure buffer is large enough to hold the data we need to load.
// Reallocates buffer if necessary, returns FALSE if unable to do so.
BOOL COpenTrapDoc::Check_Buffer_Size(DWORD data_size)
{
DWORD data_size_K;
char * new_buf;
if (data_size < (g_intLogSizeK * 1024)) // If buffer is large enough,
return TRUE; // Nothing to do, so signal success.
data_size_K = (data_size / 1024) + 16; // Calculate size needed; add 16K to allow further logging.
if (data_size_K < 2048) // Upper limit is 2048K
data_size_K = 2048;
new_buf = (char *) realloc(g_pBufferStart, data_size_K * 1024); // Try to reallocate buffer.
if (new_buf) // If successful,
{
g_pBufferStart = g_pNextRec = new_buf; // Reset pointers,
g_intLogSizeK = data_size_K; // set new buffer size,
return TRUE; // and signal success.
}
else // Otherwise,
return FALSE; // signal failure.
}
// Rebuilds record pointers after a log is loaded from disk
// or the buffer has been reallocated.
// On exit, g_pLastRecord points to the last record in the
// file and g_pNextRec points to the position for the
// next record to be added.
void COpenTrapDoc::Fix_Pointers(DWORD count)
{
struct packed_record * pr = NULL, *lr = NULL;
DWORD i;
BeginWaitCursor();
g_pNextRec = g_pBufferStart; // Point to beginning of buffer.
g_pLastRecord = NULL; // First record has no previous record.
for (i = 1; i <= count; i++)
{
pr = (packed_record *) g_pNextRec; // Update record pointer.
pr->prev_record = g_pLastRecord; // Set previous record pointer.
pr->pr_file1 = NULL;
if (pr->pr_function == IFSFN_CLOSE) // Was it a Close event?
{
lr = pr; // Start looking with current record.
while ((lr = lr->prev_record)) // Look back until beginning of file is reached
{
if (pr->pr_handle == lr->pr_handle) // for an event with the same file handle...
{
if (lr->pr_function == IFSFN_OPEN) // that was an Open....
{
pr->pr_file1 = lr->pr_file1; // if found, point to its filename string.
break;
}
}
}
}
g_pNextRec += sizeof(packed_record); // Calculate string position.
if (pr->pr_file1 == NULL) // If string pointer is not already set,
pr->pr_file1 = g_pNextRec; // Set it to current buffer position.
while (*g_pNextRec++); // Skip string.
if (i == count) // Set next record pointer.
pr->next_record = NULL;
else
pr->next_record = (packed_record *) g_pNextRec;
g_pLastRecord = pr; // Save pointer for next record.
}
EndWaitCursor();
}
// Creates a text file using the contents of the log buffer.
void COpenTrapDoc::Write_Text_Log(CString file_name)
{
HANDLE file_handle;
struct packed_record * p = (struct packed_record *) g_pBufferStart;
char workbuf[1024];
DWORD havewritten;
int recs_out = 0, rec_num = 0;
file_handle=CreateFile(file_name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0,0);
m_bIsExporting = TRUE;
while(TRUE)
{
++rec_num;
if ((g_bWriteFiltered ? Filter_Record(p) : TRUE))
{
++recs_out;
Packed_to_ASCII(rec_num, p, workbuf);
WriteFile(file_handle, workbuf, strlen(workbuf), &havewritten, NULL);
}
if ( (p = p->next_record) == NULL)
break;
}
if (g_bWriteFiltered && (recs_out == 0))
{
lstrcpy(workbuf, "No records found matching current filter criteria\r\n");
WriteFile(file_handle, workbuf, strlen(workbuf), &havewritten, NULL);
}
CloseHandle(file_handle);
m_bIsExporting = FALSE;
}
// Takes pointer to packed record in memory buffer
// and formats it as ASCII text into a buffer provided by the caller.
void COpenTrapDoc::Packed_to_ASCII(int rec_num, struct packed_record *p, char *b)
{
char *t = b, *tl, *fname, *func, *pgm;
char status[3] = {0,0,0};
static char dummy_name[] = "a file on drive x:";
if (strlen(p->pr_file1) > 2)
fname = p->pr_file1; // Default to current filename.
else
{
fname = dummy_name;
dummy_name[16] = *p->pr_file1;
}
if (m_bIsExporting && g_bCommaDelimited)
{
switch (p->pr_function)
{
case IFSFN_OPEN:
status[0] = 'O';
break;
case IFSFN_CLOSE:
status[0] = 'C';
break;
default:
status[0] = 'U';
}
status[1] = p->pr_error ? '*' : ' ';
func = status;
}
else
{
if (p->pr_function == IFSFN_OPEN)
func = (p->pr_error) ? "failed to open" : "opened";
else
{
if (p->pr_function == IFSFN_CLOSE)
func = (p->pr_error) ? "failed to close" : "closed";
else
func = (p->pr_error) ? "failed to do who knows what to" : "did who knows what to";
}
}
pgm = (p->pr_program[0] == '\0') ? "<unknown>" : p->pr_program;
tl = ctime(&(p->pr_time.time));
if (m_bIsExporting && g_bCommaDelimited)
{
if (g_bExportRecNums)
t += sprintf(t, "%06u,\"%s\",\"%s\",\"%s\",\"%.8s.%hu\"\r\n", rec_num, pgm, func, fname, &tl[11], p->pr_time.millitm);
else
t += sprintf(t, "\"%s\",\"%s\",\"%s\",\"%.8s.%hu\"\r\n", pgm, func, fname, &tl[11], p->pr_time.millitm);
}
else
{
if (m_bIsExporting ? g_bExportRecNums : g_bShowNums)
t += sprintf(t, "%06u %s %s %s at %.8s.%hu\r\n", rec_num, pgm, func, fname, &tl[11], p->pr_time.millitm);
else
t += sprintf(t, "%s %s %s at %.8s.%hu\r\n", pgm, func, fname, &tl[11], p->pr_time.millitm);
}
*t = '\0';
}
// Sets flag if any of the view filters are in effect.
void COpenTrapDoc::SetFilterFlag(void)
{
g_bUseFilters = (g_intFilterEvents != 0) ||
g_bFilterErrorsOnly ||
g_bFilterFileExt ||
g_bFilterFileName ||
g_bFilterModule;
}
// Determines whether or not the specified record matches
// the current filter criteria.
BOOL COpenTrapDoc::Filter_Record(void * p)
{
const packed_record* const r = (packed_record*) p;
BOOL result = TRUE;
if (g_bUseFilters)
{
switch (g_intFilterEvents)
{
case 0: break;
case 1: result = (r->pr_function == IFSFN_OPEN); break;
case 2: result = (r->pr_function == IFSFN_CLOSE);
}
if (result && g_bFilterErrorsOnly)
result = (r->pr_error !=0);
if (result && g_bFilterFileName)
result = Wildcard_Compare(r->pr_file1, TRUE);
if (result && g_bFilterFileExt)
result = Wildcard_Compare(r->pr_file1, FALSE);
if (result && g_bFilterModule)
{
if (g_strFilterModuleName.IsEmpty())
result &= (*r->pr_program == '0');
else
result &= (g_strFilterModuleName.CompareNoCase(r->pr_program) == 0);
}
}
return result;
}
// Function used to check a filename or extension filter using wildcards.
// Input:
// s1 = Start of buffer containing a fully qualified filename in ASCIIZ format.
// If "which" parameter indicates:
// TRUE = filename;
// FALSE = extension.
// Returns TRUE if comparison succeeds.
// Note: This function is case-sensitive, but in this
// program, filenames and filters are always uppercase-only.
BOOL COpenTrapDoc::Wildcard_Compare(char *buffer, BOOL which)
{
const char *s1 = buffer;
const char *s2;
BOOL sresult = TRUE; // Default comparison result is TRUE.
s2 = NULL;
while (*s1) // Loop to end of buffer.
{
if (*s1 == (which ? '\\' : '.')) // Is character a backslash/dot?
s2 = s1; // save position if so.
++s1; // Next character.
}
if (s2) // Was a backslash/dot found?
{
s1 = s2 + 1; // Start comparison at first char after the backslash/dot.
s2 = (which ? g_strFilterFileName : g_strFilterFileExt);
while (*s1 && *s2) // Loop until end of either string in reached.
{
if (*s1 != *s2) // Chars match?
{
if (*s2 != '?') // Was filter char not a "?" ?
{
if (*s2 == '*') // If not, was it a "*"?
break; // Done if so; comparison succeeds.
sresult = FALSE; // Otherwise, we're still done but comparison fails.
break;
}
}
++s1;
++s2;
}
if (sresult)
{
if (which)
// For filenames, comparison must have stopped while pointing at:
// Either a dot or the end of the filename string,
// And either an asterisk or the end of the filter string.
return (*s2 == '*') || ((*s1 == '.' || *s1 == '\0') && (*s2 == '\0'));
else
// For extensions, comparison must have stopped while pointing
// at either the end of the filename string or an asterisk in the filter string.
return (*s1 == '\0' || *s2 == '*');
}
else
return FALSE;
}
// If we got this far, the trailing dot/backslash was not found.
else
// So if we're checking the filename, return false.
// If we're checking the extension, return TRUE if the filter
// string is either empty or just the "*" wildcard.
return which ? FALSE : (g_strFilterFileExt.IsEmpty() || g_strFilterFileExt[0] == '*');
}